import { PlayerBattleProperty } from "./types";
import { RootState } from "../types";
import { keepDecimal, accumulateObject } from "@/util/util";
import { getEquipProps } from "@/const/equips/equipment";
import {
  equipTotalProps,
  EquipTotalPropsType
} from "@/const/equips/equipConst";
export type Getters = {
  // common
  userPropertyCHP(state: RootState): number;
  playerBattleProperty(state: RootState): PlayerBattleProperty;
  wearEquipAverageLevel(state: RootState): number;
};

export const playerGetters: Getters = {
  userPropertyCHP: state => {
    return state.userProperty.CHP;
  },
  playerBattleProperty: state => {
    const { userProperty } = state;
    const equipAddition: EquipTotalPropsType = accumulateObject(
      equipTotalProps,
      ...Object.values(state.userWearableEquipments).map(m => getEquipProps(m))
    );
    const STR = Math.max(
      keepDecimal(
        (userProperty.STR + equipAddition.STR) * (1 + equipAddition.STRP),
        0
      ),
      1
    );
    const VIT = Math.max(
      keepDecimal(
        (userProperty.VIT + equipAddition.VIT) * (1 + equipAddition.VITP),
        0
      ),
      1
    );
    const DEX = Math.max(
      keepDecimal(
        (userProperty.DEX + equipAddition.DEX) * (1 + equipAddition.DEXP),
        0
      ),
      1
    );
    const HP = Math.max(
      keepDecimal(
        (5 * VIT + equipAddition.HP + userProperty.HP) *
          (1 + equipAddition.HPP),
        0
      ),
      1
    );
    if (userProperty.CHP > HP) {
      userProperty.CHP = HP;
    } else if (userProperty.CHP < 0) {
      userProperty.CHP = 0;
    }
    return {
      STR: STR,
      VIT: VIT,
      DEX: DEX,
      HP,
      CHP: userProperty.CHP,
      RHP: keepDecimal(
        (VIT / 10 + equipAddition.RHP) * (1 + equipAddition.RHPP),
        1
      ),
      ATK: Math.max(
        keepDecimal(
          (STR / 250 + 1) *
            (0.5 * STR + equipAddition.ATK) *
            (1 + equipAddition.ATKP),
          2
        ),
        1
      ),
      DEF: Math.max(
        keepDecimal(
          (VIT / 250 + 1) *
            (0.5 * VIT + equipAddition.DEF) *
            (1 + equipAddition.DEFP),
          2
        ),
        1
      ),
      AS: Math.max(
        Math.min(
          keepDecimal(
            (1 + userProperty.DEX / 250 + equipAddition.AS) *
              (1 + equipAddition.ASP),
            2
          ),
          2.5
        ),
        0.1
      ),
      CRR: Math.max(
        Math.min(
          keepDecimal(
            (0.05 + DEX / (DEX + 150) + equipAddition.CRR) *
              (1 + equipAddition.CRRP),
            4
          ),
          1
        ),
        0
      ),
      CRD: Math.max(
        keepDecimal((1.5 + equipAddition.CRD) * (1 + equipAddition.CRDP), 4),
        0.5
      )
    };
  },
  wearEquipAverageLevel: state => {
    const aveLevelArr = Object.values(state.userWearableEquipments).map(
      ({ level }) => level
    );
    if (aveLevelArr.length) {
      const aveLevel = aveLevelArr.reduce((pre, now) => {
        return pre + now;
      }, 0);
      return Math.ceil(aveLevel / aveLevelArr.length);
    }
    return 0;
  }
};
